package org.mms.service.impl;

import org.mms.exception.BusinessException;
import org.mms.pojo.dto.MaterialApplicationDto;
import org.mms.pojo.entity.Material;
import org.mms.pojo.entity.MaterialApplication;
import org.mms.pojo.entity.User;
import org.mms.pojo.request.MaterialApplicationCreateRequest;
import org.mms.pojo.request.MaterialApplicationReviewRequest;
import org.mms.pojo.request.MaterialApplicationUpdateRequest;
import org.mms.repository.MaterialApplicationRepository;
import org.mms.repository.MaterialRepository;
import org.mms.repository.UserRepository;
import org.mms.service.MaterialApplicationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class MaterialApplicationServiceImpl implements MaterialApplicationService {

    @Autowired
    private MaterialApplicationRepository applicationRepository;
    @Autowired
    private MaterialRepository materialRepository;
    @Autowired
    private UserRepository userRepository;

    private static final String STATUS_PENDING = "待审核";
    private static final String STATUS_APPROVED = "通过";
    private static final String STATUS_REJECTED = "未通过";

    @Override
    public List<MaterialApplication> list() {
        return applicationRepository.findAll();
    }

    @Override
    public MaterialApplication getById(Long id) {
        return applicationRepository.findById(id)
                .orElseThrow(() -> new BusinessException("物资申请记录不存在"));
    }

    @Override
    public MaterialApplication create(MaterialApplicationCreateRequest request) {
        Material material = materialRepository.findById(request.getMaterialId())
                .orElseThrow(() -> new BusinessException("物资不存在 (ID: " + request.getMaterialId() + ")"));

        // 库存检查
        if (request.getQuantity() <= 0) {
            throw new BusinessException("申请数量必须大于 0");
        }
        if (material.getQuantity() < request.getQuantity()) {
            throw new BusinessException(String.format("物资 '%s' 库存不足 (当前库存: %d)",
                    material.getName(), material.getQuantity()));
        }

        User applicant = userRepository.findById(request.getApplicantId())
                .orElseThrow(() -> new BusinessException("指定的申请员工不存在 (ID: " + request.getApplicantId() + ")"));

        MaterialApplication application = new MaterialApplication();
        application.setMaterial(material);
        application.setQuantity(request.getQuantity());
        application.setApplicant(applicant);
        application.setApplyReason(request.getApplyReason());
        application.setStatus(STATUS_PENDING); // 新申请总是待审核

        return applicationRepository.save(application);
    }

    @Override
    public MaterialApplication update(MaterialApplicationUpdateRequest request) {
        MaterialApplication application = applicationRepository.findById(request.getId())
                .orElseThrow(() -> new BusinessException("物资申请记录不存在"));

        // 检查是否为“待审核”状态
        if (!STATUS_PENDING.equals(application.getStatus())) {
            throw new BusinessException("只能修改状态为 '待审核' 的申请");
        }

        Material material = materialRepository.findById(request.getMaterialId())
                .orElseThrow(() -> new BusinessException("物资不存在 (ID: " + request.getMaterialId() + ")"));

        // 再次检查库存
        if (request.getQuantity() <= 0) {
            throw new BusinessException("申请数量必须大于 0");
        }
        // 如果修改增加了申请量，检查库存是否足够；如果减少了，无需检查
        if (request.getQuantity() > application.getQuantity() && material.getQuantity() < (request.getQuantity() - application.getQuantity())) {
            int needed = request.getQuantity() - application.getQuantity();
            throw new BusinessException(String.format("物资 '%s' 库存不足以增加申请数量 (当前库存: %d, 需额外增加: %d)",
                    material.getName(), material.getQuantity(), needed));
        } else if (material.getQuantity() < request.getQuantity()) {
            // 如果修改了物资或直接设置的数量大于库存
            throw new BusinessException(String.format("物资 '%s' 库存不足 (当前库存: %d, 申请数量: %d)",
                    material.getName(), material.getQuantity(), request.getQuantity()));
        }

        application.setMaterial(material);
        application.setQuantity(request.getQuantity());
        application.setApplyReason(request.getApplyReason());

        return applicationRepository.save(application);
    }


    @Override
    @Transactional
    public MaterialApplication review(MaterialApplicationReviewRequest request) {
        MaterialApplication application = applicationRepository.findById(request.getId())
                .orElseThrow(() -> new BusinessException("物资申请记录不存在"));

        // 检查是否为“待审核”状态
        if (!STATUS_PENDING.equals(application.getStatus())) {
            throw new BusinessException("只能审核状态为 '待审核' 的申请");
        }

        User reviewer = userRepository.findById(request.getReviewerId())
                .orElseThrow(() -> new BusinessException("审核人不存在 (ID: " + request.getReviewerId() + ")"));

        // 验证审核状态
        if (!STATUS_APPROVED.equals(request.getStatus()) && !STATUS_REJECTED.equals(request.getStatus())) {
            throw new BusinessException("无效的审核状态，只能是 '通过' 或 '未通过'");
        }

        application.setReviewer(reviewer);
        application.setStatus(request.getStatus());
        application.setReviewComments(request.getReviewComments());
        application.setReviewTime(LocalDateTime.now());

        return applicationRepository.save(application);
    }

    @Override
    public void delete(Long id) {
        MaterialApplication application = applicationRepository.findById(id)
                .orElseThrow(() -> new BusinessException("物资申请记录不存在 (ID: " + id + ")"));

        if (!STATUS_PENDING.equals(application.getStatus())) {
            throw new BusinessException("只能删除状态为 '待审核' 的申请");
        }
        applicationRepository.deleteById(id);
    }
}